﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace SellAndBuy.Domain.Core
{
    /// <summary>
    /// Repository main interface
    /// </summary>
    /// <typeparam name="TEntity">entity type of the repository</typeparam>
    /// <typeparam name="TID">id of the entity</typeparam>
    public interface IRepository<TEntity, in TID> where TEntity : IAggregateRoot
    {
        /// <summary>
        /// Get the unit of work in this repository
        /// </summary>
        IUnitOfWork UnitOfWork { get; }

        /// <summary>
        /// Add an item to repository
        /// </summary>
        /// <param name="item">item to add</param>
        void Add(TEntity item);

        /// <summary>
        /// Delete item 
        /// </summary>
        /// <param name="item">Item to delete</param>
        void Remove(TEntity item);

        /// <summary>
        /// Update entity into the repository
        /// </summary>
        /// <param name="item">Item with changes</param>
        void Update(TEntity item);

        /// <summary>
        /// Get specific entity by id
        /// </summary>
        /// <param name="id">id</param>
        /// <returns>requested entity</returns>
        TEntity Find(TID id);

        /// <summary>
        /// Get specific entity by query (Expression)
        /// </summary>
        /// <param name="query">Expression to evaluate</param>
        /// <returns>Item matching query</returns>
        TEntity FindBy(Expression<Func<TEntity, bool>> query);
    }
}